{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Styles, Scales, and Shapes - 🐭" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Styles and Shapes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*Styling* - The styling is handled through something call CSS (Cascading Style Sheets), but we can specifically handle this within our D3.js code. Here is a list of typical style changes. \n", "* fill - the color inside the shape\n", "* stroke - the border of the shape\n", "* opacity - the transparency of the shape\n", "* Note: there are more combinations, but these are the basics and covers a good amount of styling.\n", "\n", "*Shapes* - At this point, we have been using circles primarily for out designs. There are few other shapes we need to cover and what is needed to draw these.\n", "* Circles (\"circle\") - cx, cy, r\n", "* Rectangles (\"rect\") - x, y, width, height\n", "* Line (\"line\") - x1, y1, x2, y2\n", "* Text (\"text\") - x, y\n", "* Paths (\"path\") - these are by far the most complicate shapes, and will require further discussion throughout these notebooks\n", "* Note: There are ellipse, polylines, and polygons, but these are RARELY used in D3.js\n", ". " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First things, first... Let's bring back our last project for Part 2." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```javascript\n", "var dataset = [3, 5, 5, 6, 15, 18]\n", "```" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the above example, we used .attr(ibute) for the attributes of the given shape. We can use another function called .style() to add the CSS styling directly to the shape.\n", "\n", "For our first example, we make these *purple circles with a black border that is 3 px in width*" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Your Turn** - Create the 6 circles with the stroke: blue, stroke-width: 5px, and fill: lightgrey" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Again, the cool thing about D3.js is that we can use the data to style as well. Here is the same plot, but the stroke-width will be the value of our data set." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Color Scales" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For the most part, this is not very helpful. One way to make this more useful is to use color based on our data, or in other words, the darker the color, the larger the value. \n", "\n", "To implement this, I would HIGHLY suggest visit [color-scales](https://github.com/d3/d3-scale-chromatic). As mentioned in the article, the color scales were created using Cynthia A. Brewer’s [ColorBrewer](https://colorbrewer2.org/). ColorBrewer was designed to help designers find color-blind safe and print and copier safe color palette. ColorBrewer is my (and several other programming languages) “go-to” color palette." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For this, I will be choosing the Sequential (Single Hue) - Purple color. For these color palettes, they are expecting a value between 0 to 1, where 0 is the far-left of the color palette, the far-right is 1." ] }, { "attachments": { "purple.PNG": { "image/png": "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" } }, "cell_type": "markdown", "metadata": {}, "source": [ "![purple.PNG](https://raw.githubusercontent.com/dudaspm/d3plotbook/main/purple.PNG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For now, to get our values between 0 and 1. I will take the largest value in our array (dataset, which is 18) and divide all of our values by this. Meaning, 3 will become 3/18, 5 will be 5/18 and so on." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Cool! We have some color! Though, we want to setup a way for our data to fit the 0 to 1 range withOUT needing us to manaully adding the largest value. There is a way to do this using [scaling](https://github.com/d3/d3-scale). Scaling allows use to create a range of values based on our data set. There are multiple types of scaling.For continuous data, or data with numeric values (Linear, Power, Log, Identity, Time, Radial). There are types of scaling, but for now we will focus on these." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Scale Linear (d3.scaleLinear)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's start by creating a scaling function called between0and1. To do this we will need two things:\n", "* the **.domain()** which is the lowest and highest number that will be given to the function. This is usually the smallest number in our array or 3, and largest number, 18. \n", "* the **.range()** is the range of values we want to map to, as in we want all numbers to be within 0 to 1. \n", "\n", "Our smallest number (3), will be mapped 0 and our largest number (18) mapped to 1." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "tags": [ "remove-input" ] }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "
(No Audio) Figure showing how are list [5,3,16,5,6,18] maps to the domain and range [0,1]
\n", "
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "
(No Audio) Figure showing how are list [5,3,16,5,6,18] maps to the domain and range [0,1]
\n", "
" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "

\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "

\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Again, though, we are still manually putting these values into our boundries. That's why there are built in functions to help AUTOMAGICALLY find the lowest and highest values in an array. \n", "* **d3.max()** - finds the max value in the array\n", "* **d3.min()** - finds the min value in the array\n", "* **d3.extent()** - finds both the min and max values in an array" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "

\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "

\n", "" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "

\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "

\n", "" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "

\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "

\n", "" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

So, when to use d3.extent or d3.min/d3.max? This is a good example of this case. Right now,

\n", "\n", "\n", "```javascript\n", "const color = d3.scaleLinear().range([0,1]).domain(d3.extent(dataset))\n", "```\n", "\n", "\n", "

assumes that our lowest number, 3, is mapped to 0. Though, in some cases, we want 0 to be mapped to 0. Meaning we should use

\n", "\n", "\n", "```javascript\n", "const color = d3.scaleLinear().range([0,1]).domain([0,d3.max(dataset)])\n", "```" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Shapes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Rectangles" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For rectangles, the x,y is the origin of the rectangle (again in the top-lefthand corner). Right now, we are missing a rectangle, well, not missing it, it just off the canvas. For data point 3, index 0, the x position is 15, and the y position is the height. Meaning, we need to correct this. Also, we are not using the space very well. This was true with our circles, but let's see if we can fix this issue here as well. The best way to do this is to create margins. For now, let's just set a margin of 30. 30 on the top, bottom, left, and right. We will do this using the scaleLinear function for both the x and y axis." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Text" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, we add some text next to our boxes. For the most part, we will be using the same code as our rectangles. Let's take a look." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Adding in the text, the only additional piece we need to add is what the .text() will be. In this case, I am again using the data to add specific data related text to the screen. If we take a particular look at this function, we can see how we used both text and data together." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ".text((d,i) => \"x: \"+d+\" y: \"+i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using the \"x: \", the plus sign (+), and d will combine or concatenate the two to make one string" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The last thing that needs to be adjusted is the fact that both the rectangle and the text occupy the same x,y coordinate, which means they overlap a bit. Also, the text for our last rectangle is off the canvas. So, let's adjust both of these." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Lines" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, we have lines. Lines are similar to circles, rectangles, and text. You need a starting x,y, and similar to the rectangle you need secondary dimension (width/height), whereas lines need an ending x,y position. I think there can be a misconception about lines, based on “line graphs.” Line graphs (as seen below) look like a single line but fluctuations here and there when a better way to think about lines independent of one another. Paths (talked about next) are where we will be able to think about one, continuous line." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{list-table}\n", ":header-rows: 0\n", "\n", "* - \"expected\n", " - \"actual\n", "* - Figure 1 -
How you might assume the line shape would work.\n", " - Figure 2 -
How the line shape actually works.\n", "```" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To create a line chart from these lines would require several changes. Here is an example of how to do it, but there is a MUCH simpler way using paths, which we will talk about in a second." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see, this is not the most elegant way to handle creating a line." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Paths" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, we have paths. Up to this point, we have been focusing on the idea \"for each data point, we create a shape or object.\" Paths require multiple data points to create the shape/object. We can use a function to create our line. We can either do this in a new (separate) cell or in with the code itself. Let's build it in our design. " ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Your Turn" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using the template provided, create your own data set and rectangles (squares) for each data point. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%html\n", "
\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using the template provided, create your own data set and path for each data point. " ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{warning}\n", "This one is a bit tough. Using the template provided, create your own data set and path for each data point. Also, add circles at each data point and the text labels.\n", "```\n" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "
\n", "\n", "" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.5" } }, "nbformat": 4, "nbformat_minor": 4 }